home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / misc / elcheapofax.lha / fax2iff.c < prev    next >
C/C++ Source or Header  |  1993-04-08  |  4KB  |  215 lines

  1. /*
  2.  * fax2iff.c
  3.  */
  4.  
  5. #include <stdlib.h>
  6.  
  7. #include "iffp/iff.h"
  8. #include "iffp/ilbm.h"
  9. #include "iffp/packer.h"
  10. #include "faxfile.h"
  11.  
  12. void           *IFFParseBase;
  13. struct ParseInfo ParseInfo;
  14. int        verbose;
  15. int        invert;
  16.  
  17. /* Assumes malloc()ed pointer */
  18. void
  19. meminvert(unsigned char *d, int size)
  20. {
  21.     while (size >= 4) {
  22.     *(long *)d ^= 0xFFFFFFFF;
  23.     d += 4;
  24.     size -= 4;
  25.     }
  26.     while (size > 0) {
  27.     *d++ ^= 0xFF;
  28.     size--;
  29.     }
  30. }
  31.  
  32. long
  33. dobody(FILE *faxfile, struct ParseInfo *pi)
  34. {
  35.     unsigned char  *planedata;
  36.     unsigned char  *bodydata;
  37.     int         planedatasize;
  38.     int         bodydatasize;
  39.     int         lines;
  40.  
  41.     planedatasize = BytesPerRow(LINE_BITS);
  42.     bodydatasize  = MaxPackedSize(BytesPerRow(LINE_BITS));
  43.     planedata = malloc(4 + planedatasize);
  44.     bodydata  = malloc(4 + bodydatasize);
  45.  
  46.     for (lines=0;;lines++) {
  47.     unsigned char  *p, *b;
  48.     long        size;
  49.  
  50.     memset(planedata, 0, planedatasize);
  51.     size = fromfax(faxfile, planedata);
  52.     if (size == -1)
  53.         break;
  54.     if (invert)
  55.         meminvert(planedata, planedatasize);
  56.     p = planedata;
  57.     b = bodydata;
  58.     size = PackRow(&p, &b, LINE_BITS / 8);
  59.     WriteChunkBytes(pi->iff, bodydata, size);
  60.     }
  61.  
  62.     free(bodydata);
  63.     free(planedata);
  64.  
  65.     return lines;
  66. }
  67.  
  68. long
  69. dopage(FILE *faxfile, struct ParseInfo *pi)
  70. {
  71.     long        bmhdpos;
  72.     long        currpos;
  73.     int         lines;
  74.     FILE       *ifffile;
  75.     BitMapHeader    bmhd = {
  76.             LINE_BITS, 9999,    /* w, h (unknown yet) */
  77.             0, 0,            /* x, y */
  78.             1,            /* nPlanes */
  79.             mskNone,        /* masking */
  80.             cmpByteRun1,        /* compression */
  81.             0,            /* reserved1 */
  82.             0,            /* transparentcolor */
  83.             Y_DPI, X_DPI,        /* xAspect, yAspect */
  84.             LINE_BITS, 9999,    /* pageWidth, pageHeight */
  85.             };
  86.  
  87.     PushChunk(pi->iff, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN);
  88.  
  89.     /*
  90.      * This is DIRTY DIRTY DIRTY!!
  91.      * We need to update the BitMapHeader later on because we
  92.      * don't know the y size yet.
  93.      */
  94.     ifffile = (FILE *)pi->iff->iff_Stream;
  95.     bmhdpos = ftell(ifffile) + 8;
  96.     putbmhd(pi->iff, &bmhd);
  97.  
  98.     PushChunk(pi->iff, ID_ILBM, ID_BODY, IFFSIZE_UNKNOWN);
  99.  
  100.     lines = dobody(faxfile, pi);
  101.  
  102.     PopChunk(pi->iff);  /* BODY */
  103.     PopChunk(pi->iff);  /* FORM ILBM */
  104.  
  105.     /* Update BMHD */
  106.     bmhd.h = lines;
  107.     bmhd.pageHeight = lines;
  108.     currpos = ftell(ifffile);
  109.     if (fseek(ifffile, bmhdpos, SEEK_SET) == 0) {
  110.     fwrite(&bmhd, sizeof(bmhd), 1, ifffile);
  111.     fseek(ifffile, currpos, SEEK_SET);
  112.     } else {
  113.     fprintf(stderr, "fseek on iff-file failed\n");
  114.     }
  115.  
  116.     return 0;
  117. }
  118.  
  119. long
  120. dofile(char *faxname, struct ParseInfo *pi)
  121. {
  122.     FILE       *faxfile;
  123.     long        error;
  124.  
  125.     faxfile = fopen(faxname, "rb");
  126.     if (faxfile == NULL)
  127.     return 1;
  128.  
  129.     error = faxin_open_fp(faxfile, 0);
  130.  
  131.     while (error == 0 && faxin_begin_page(faxfile) == 0) {
  132.     error = dopage(faxfile, pi);
  133.     }
  134.  
  135. error:
  136.     fclose(faxfile);
  137.     return error;
  138. }
  139.  
  140.  
  141. /*
  142.  * Clean up system stuff in case of exit
  143.  */
  144. void
  145. cleanup(void)
  146. {
  147.     if (IFFParseBase) {
  148.     if (ParseInfo.iff) {
  149.         closeifile(&ParseInfo);
  150.         FreeIFF(ParseInfo.iff);
  151.     }
  152.     CloseLibrary(IFFParseBase);
  153.     }
  154. }
  155.  
  156. int
  157. main(int argc, char **argv)
  158. {
  159.     struct IFFHandle *iff;
  160.     char       *outfile = "fax.iff";
  161.     extern char    *optarg;
  162.     extern int        optind;
  163.     extern int        getopt(int, char **, char *);
  164.     int         errflg = 0;
  165.     int         c;
  166.  
  167.     while ((c = getopt(argc, argv, "io:v")) != -1) {
  168.     switch (c) {
  169.     case 'i':
  170.         invert = 1;
  171.         break;
  172.     case 'o':
  173.         outfile = optarg;
  174.         break;
  175.     case 'v':
  176.         verbose = TRUE;
  177.         break;
  178.     case '?':
  179.         errflg++;
  180.         break;
  181.     }
  182.     }
  183.  
  184.     if (errflg || optind >= argc) {
  185.     printf(
  186. "Usage: fax2iff [-o iff-file (fax.iff)] [-v] [-i (invert)] fax-files\n");
  187.     exit(EXIT_FAILURE);
  188.     }
  189.  
  190.     atexit(cleanup);
  191.  
  192.     IFFParseBase = OpenLibrary("iffparse.library", 0);
  193.     if (IFFParseBase == NULL) {
  194.     printf("Needs iffparse.\n");
  195.     exit(10);
  196.     }
  197.  
  198.     iff = AllocIFF();
  199.     ParseInfo.iff = iff;
  200.     openifile(&ParseInfo, outfile, IFFF_WRITE);
  201.     PushChunk(iff, ID_ILBM, ID_CAT, IFFSIZE_UNKNOWN);
  202.  
  203.     while (optind < argc) {
  204.     dofile(argv[optind], &ParseInfo);
  205.     optind++;
  206.     }
  207.  
  208.     PopChunk(iff);
  209.     closeifile(&ParseInfo);
  210.     FreeIFF(iff);
  211.     ParseInfo.iff = NULL;
  212.  
  213.     /*CloseLibrary(IFFParseBase);*/
  214. }
  215.